#include <rid.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#define STYLE_9
#include <unfy/unfy.h>
#include <unfy/unfp.h>

#include "../rls.h"
#include "../rlsp.h"

void
test_rule(Rls_rule *rules, Rls_recycle *rec)
{
	Rls_rule *rules2 = NULL;
	unsigned char *buf = NULL;
	size_t size = 0;
	size_t pos = 0;

	rlsp_rule_ser(rules, &buf, &size, &pos, NULL, NULL);
	pos = 0;

	if (!rlsp_rule_deserable(buf, &pos, size, NULL, NULL))
		printf("Rule is safe to deser, len is %zu\n", pos);

	pos = 0;
	rlsp_rule_deser(&rules2, buf, &pos, NULL, NULL, rec);
	rlsp_rule_print(rules2, NULL);
	rls_recycle_rule(rec, rules2, NULL, NULL);
	free(buf);
}

void
test_srch(Rls_rule *rules, Rls_recycle *rec)
{
	Rls_srch *srch = NULL;
	Rls_srch **srch_ref;
	Rls_srch *srch2;
	Rls_srch **srch_ref2;
	unsigned char *buf = NULL;
	size_t size = 0;
	size_t pos = 0;
	const char *error;
	Unfy_term *term = unfp_term_parse("(const mortal______________ "
					  "var mortals_____________)",
					  &pos, &error, &rec->unfy);
	Rls_info info;

	rls_srch(&srch, term, rules, NULL, &info, NULL, rec);
	pos = 0;
	rlsp_srch_ser(srch, &buf, &size, &pos);
	pos = 0;

	if (!rlsp_srch_deserable(buf, &pos, size))
		printf("Srch is safe to deser, len is %zu\n", pos);

	pos = 0;
	rlsp_srch_deser(&srch2, buf, &pos, rules, NULL, NULL, rec);
	unfp_bind_print(srch2->fbind);
	rlsp_srch_print(srch2, 0);

	srch_ref = &srch;
	srch_ref2 = &srch2;

	if (rls_srch_same(&info.unfy, srch_ref,
			  srch_ref2, rec) == RLS_DIF_SAME)
		printf("Srch same as original\n");

	rls_recycle_srch(rec, srch);
	rls_recycle_srch(rec, srch2);
	free(buf);
}

int
main(int argc, char *argv[])
{
	Rls_recycle rec;
	Unfy_term *head;
	Unfy_list *body;
	Rls_rule *rules = NULL;
	size_t pos = 0;
	const char *error;

	rls_recycle_init(&rec);
	head = unfp_term_parse("(const man_________________ "
			       "const socrates____________)",
			       &pos, &error, &rec.unfy);
	unfp_list_parse(&body, "()", &pos, &error, &rec.unfy);
	rls_rule_add(&rules, NULL, head, body, NULL, &rec);
	head = unfp_term_parse("(const mortal______________ "
			       "var mortals_____________)",
			       &pos, &error, &rec.unfy);
	unfp_list_parse(&body, "((const man_________________ "
			"var mortals_____________))",
			&pos, &error, &rec.unfy);
	rls_rule_add(&rules, NULL, head, body, NULL, &rec);
	test_rule(rules, &rec);
	test_srch(rules, &rec);
	rls_recycle_rule(&rec, rules, NULL, NULL);
	rls_recycle_empty(&rec);
	return 0;
}
